<template>
  <a-select
    v-model="bindValue"
    :style="{ width: '20rem' }"
    :placeholder="placeholder"
    allow-search
    :loading="inLoading"
    @popup-visible-change.once="handleLoadOptions"
    @change="
      (e) => {
        const item = OPTIONS.find((i) => e === i[valueName])
        emits('valueChange', item)
      }
    "
  >
    <template v-if="usePlus" #trigger="e">
      <a-resize-box :directions="['right']" style="width: 20rem">
        <div class="arco-select-view-single px-[4px] py-[3px] flex !items-center">
          <div class="w-full" v-if="(bindValue as any)?.length">
            <a-overflow-list>
              <a-tag
                v-for="(value, i) in bindValue"
                :key="value"
                closable
                class="!text-black bg-white flex items-center"
                @close="
                  () => {
                    ;(bindValue as any[]).splice(i as any, 1)
                  }
                "
              >
                {{ OPTIONS.find((e) => e[valueName] === value)[labelName] }}
              </a-tag>
            </a-overflow-list>
          </div>
          <p class="text-gray-400 ml-1 mt-0.5" v-else>{{ placeholder }}</p>
        </div>
      </a-resize-box>
    </template>
    <a-option v-for="item in OPTIONS" :value="item[valueName]">{{ item[labelName] }}</a-option>
  </a-select>
</template>

<script lang="ts" setup>
type IValue = string | number
const props = withDefaults(
  defineProps<{
    modelValue: IValue | IValue[]
    options?: Record<string, IValue>[] | string[] | Record<string, IValue> // 默认OPTIONS，就算使用了API，也会有这个
    api?: (...args: any) => IResList
    resFormat: (...args: any) => any[]
    apiParams?: any
    labelName: string
    valueName: string
    placeholder: string
    isArray?: boolean
    isObject?: boolean
    usePlus?: boolean
  }>(),
  {
    resFormat: (e: any) => e.list,
    labelName: 'label',
    valueName: 'value',
    placeholder: '请选择',
  },
)
const emits = defineEmits(['update:modelValue', 'valueChange'])
const bindValue = useVModel(props, 'modelValue', emits)

const OPTIONS = ref<any[]>([])
const inLoading = ref(false)

if (props.options) {
  // 使用默认options
  const { options, labelName, valueName } = props
  if (props.isArray)
    OPTIONS.value = (options as string[]).map((e, i) => {
      const obj: Record<string, any> = {}
      obj[labelName] = e
      obj[valueName] = i
      return obj
    })
  if (props.isObject)
    OPTIONS.value = Object.entries(options as Record<string, IValue>).map(([label, value]) => {
      const obj: Record<string, any> = {}
      obj[labelName] = label
      obj[valueName] = value
      return obj
    })
}

async function handleLoadOptions() {
  if (props.api) {
    inLoading.value = true
    const resData = await props.api(props.apiParams)
    const list = props.resFormat(resData)
    OPTIONS.value.push(...list)
    await nextTick()
    inLoading.value = false
  }
}
</script>
